using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Windows.Forms;
using System.Drawing;
using System.Threading;
using System.Collections;
using System.IO;
/*
 * TODO: Proxy support
 * TODO: Show weather picker on startup if no locations set (and welcome dialog?)
 */

namespace Weathertastic
{
    /* Update handler */
    public delegate void WeatherUpdateEventHandler();

    class Engine
    {
        private NotifyIcon notifyIcon;
        private Icon icon;
        private WeatherInfo _weatherInfo;
        private ArrayList a_weatherInfo;
        private WeatherMenu wMenu;
        private Settings Settings;
        private System.Windows.Forms.Timer _timer;

        // Events
        private delegate void DownloadDelegate();

        public Engine()
        {
            // Setup the timer
            _timer = new System.Windows.Forms.Timer();
            _timer.Interval = 1800000;  // 30 minutes
            _timer.Tick += new EventHandler(UpdateWeather);
            _timer.Start();

            // Construct the context menu and add it to the notify icon
            wMenu = new WeatherMenu(this);
            wMenu.BuildMenu(new ArrayList());   // Initial menu should be blank

            // Setup the notify icon
            notifyIcon = new NotifyIcon();
            Bitmap b = (Bitmap)Image.FromFile(Application.StartupPath + "\\images\\world.png"); 
            notifyIcon.Icon = Icon.FromHandle(b.GetHicon());
            notifyIcon.Visible = true;
            notifyIcon.Text = "Weathertastic";
            notifyIcon.DoubleClick += new EventHandler(notifyIcon_DoubleClick);
            notifyIcon.ContextMenu = wMenu.GetMenu();
            
            // Get the weather
            UpdateWeather(null, null);
        }

        public void notifyIcon_DoubleClick(object sender, EventArgs e)
        {
            UpdateWeather(this, null);
        }

        public void UpdateWeather(object sender, EventArgs e)
        {
            notifyIcon.Text = "Weathertastic is updating...";
            Bitmap b = (Bitmap)Image.FromFile(Application.StartupPath + "\\images\\updating.png");
            notifyIcon.Icon = Icon.FromHandle(b.GetHicon());
            
            // Fire off the delegate to download...parse...display weather information
            DownloadDelegate del = new DownloadDelegate(DownloadWeather);
            del.BeginInvoke(new AsyncCallback(OnWeatherDownloaded), null);
        }

        public void DownloadWeather()
        {
            DownloadFile Downloader = new DownloadFile();
            Settings = new Settings();

            // Loop through each location and download the weather xml file
            Locations locs = new Locations();
            foreach (Location loc in locs)
            {
                // TODO: Uncomment for release
                char cUnit = Settings.UseImperial ? 'f' : 'm';
                Downloader.Download("http://xoap.weather.com/weather/local/" + loc.Station + "?cc=*&unit="+cUnit.ToString()+"&dayf=2", "weather-"+loc.Station+".xml");
            }
            Settings = null;
            locs = null;
        }

        public void OnWeatherDownloaded(IAsyncResult ar)
        {
            a_weatherInfo = new ArrayList();
            Locations locs = new Locations();
            foreach (Location loc in locs)
            {
                // Parse each location and place the WeatherInfo object into an ArrayList
                ParseWeather _parsedWeather = new ParseWeather(Application.StartupPath + "\\weather-" + loc.Station + ".xml");
                a_weatherInfo.Add(_parsedWeather.WeatherInfo);
            }

            OnWeatherUpdated();
        }

        public void OnWeatherUpdated()
        {
            wMenu.BuildMenu(a_weatherInfo);
            notifyIcon.ContextMenu = wMenu.GetMenu();
            string sStationDefault = string.Empty;
            _weatherInfo = new WeatherInfo();

            // Find out the default station so we can set the notify icon accordingly
            Locations locs = new Locations();
            foreach (Location loc in locs)
            {
                if (loc.Default)
                     sStationDefault = loc.Name;
            }

            locs = null;

            // Get weather info for default location
            foreach (WeatherInfo WeatherInfo in a_weatherInfo)
            {
                if (WeatherInfo.LocationName.Equals(sStationDefault))
                    _weatherInfo = WeatherInfo;
            }

            // Check that there is a a default set, if not assign the first location
            if (_weatherInfo.LocationName.Equals(string.Empty) && a_weatherInfo.Count > 0)
                _weatherInfo = (WeatherInfo)a_weatherInfo[0];

            if (_weatherInfo.Icon > -1)
            {
                Bitmap b = (Bitmap)ConditionToIcon.GetIcon(_weatherInfo.Icon);
                notifyIcon.Icon = Icon.FromHandle(b.GetHicon());
                notifyIcon.Text = "It's " + _weatherInfo.Condition + " in " + _weatherInfo.LocationName;
            }

            else
            {
                // Problem getting the XML file or parsing it
                Bitmap b = (Bitmap)Image.FromFile(Application.StartupPath + "\\images\\warning.png");
                notifyIcon.Icon = Icon.FromHandle(b.GetHicon());
                if (a_weatherInfo.Count > 0)
                    notifyIcon.Text = "Error retrieving weather data.";
                else
                    notifyIcon.Text = "No weather locations.";
            }
        }

        public void Dispose()
        {
            Locations locs = new Locations();
            foreach (Location loc in locs)
            {
                string sFile = "weather-" + loc.Station + ".xml";
                if (File.Exists(sFile))
                    File.Delete(sFile);

            }
            notifyIcon.Visible = false;
            notifyIcon = null;
        }

        /// <summary>
        /// Entry point for the application
        /// </summary>
        [STAThread]
        public static void Main()
        {
            Engine weathertastic = new Engine();
            Application.EnableVisualStyles();
            Application.Run();
        }
    }
}
